package cn.brilliantfuture.commentry.delivery.impl;

import java.text.MessageFormat;
import java.util.Date;
import java.util.List;
import java.util.Map;

import javax.ejb.EJB;
import javax.ejb.Stateless;
import javax.jws.WebService;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;

import net.sf.json.JSONObject;

import org.apache.log4j.Logger;
import org.jboss.wsf.spi.annotation.WebContext;

import com.acsm.commons.sms.AlidayuSMS;
import com.acsm.commons.sms.SaveSmsInfo;

import cn.brilliantfuture.commentry.constants.OrderConstant;
import cn.brilliantfuture.commentry.delivery.StorageTakeoutMessageRemote;
import cn.brilliantfuture.commentry.delivery.StorageTakeoutMessageWebService;
import cn.brilliantfuture.commentry.entity.EmailInfo;
import cn.brilliantfuture.commentry.entity.OrderInformation;
import cn.brilliantfuture.commentry.entity.PickRecords;
import cn.brilliantfuture.commentry.entity.ProductBatch;
import cn.brilliantfuture.commentry.entity.SmsInfo;
import cn.brilliantfuture.commentry.entity.StorageGridPurchaserNews;
import cn.brilliantfuture.commentry.inform.InformMessageLocal;
import cn.brilliantfuture.commentry.order.WorkflowMessageLocal;
import cn.brilliantfuture.commentry.util.CommEntryUtil;
import cn.brilliantfuture.commentry.util.DateTimeHelper;
import cn.brilliantfuture.commentry.util.EMAILScheduler;
import cn.brilliantfuture.commentry.util.RESTUtil;
import cn.brilliantfuture.commentry.util.SMSScheduler;

/**
 * 
 * Title: Communication Entry
 * 
 * Author:  LiTian  
 *
 * Date: 2012-8-23
 * 
 * Description:
 * 
 */
@Stateless
@WebService(endpointInterface = "cn.brilliantfuture.commentry.delivery.StorageTakeoutMessageWebService")
@WebContext(contextRoot = "/commentry", urlPattern = "/StorageTakeoutMessageWebService")
public class StorageTakeoutMessageImpl implements StorageTakeoutMessageRemote,
		StorageTakeoutMessageWebService {
	
	private static Logger logger = Logger.getLogger(StorageTakeoutMessageImpl.class);
	
	@PersistenceContext
	EntityManager entityManager;
	
	@EJB InformMessageLocal informMessage;
	
	@EJB WorkflowMessageLocal workflowMessageLocal;

	/*@SuppressWarnings("unchecked")
	public int safeStorageTakeout(String deviceSn, int gridNo, String storageRfid,
			String timestamp) {
		logger.info("deviceSn -> " + deviceSn + " gridNo -> " + gridNo + " storageRfid -> " + storageRfid + " timestamp -> " + timestamp);
		
		Date takeoutTime = DateTimeHelper.strToDateTime(timestamp, DateTimeHelper.DEFAULT_DATE_TIME_NOT_SPACE_FORMAT);
		
		List<StorageServiceInfo> storageServiceInfoList = entityManager.createQuery("select ssi from StorageServiceInfo ssi where ssi.enable = false and ssi.deliveryTime is not null and ssi.takeoutTime is null and ssi.storageRfid = '" + storageRfid + "'").getResultList();
		if (null == storageServiceInfoList || storageServiceInfoList.size() == 0)
			return 6;
		
		StorageServiceInfo storageServiceInfo = storageServiceInfoList.get(0);
		
		List<OrderInformation> orderInfoList = entityManager.createQuery("select oi from OrderInformation oi where oi.deleted = 0 and oi.orderInformationId = " + storageServiceInfo.getOrderInformationId()).getResultList();
		if (null == orderInfoList || orderInfoList.size() == 0)
			return 6;
		
		OrderInformation orderInformation = orderInfoList.get(0);
		
		List<StorageGridPurchaserNews> sgpnList = entityManager.createQuery("select sgpn from StorageGridPurchaserNews sgpn where closing = 0 and sgpn.refund = 0 and sgpn.delivery = 1 and sgpn.orderInformationNumber = '" + orderInformation.getNumber() + "'").getResultList();
		if (null == sgpnList || sgpnList.size() == 0)
			return 6;
		
		List<StorageChargeInfo> storageChargeInfoList = entityManager.createQuery("select sci from StorageChargeInfo sci where sci.deleted = 0 order by sci.storageChargeInfoId desc").setMaxResults(1).getResultList();
		if (null == storageChargeInfoList || storageChargeInfoList.size() == 0)
			return 6;

		StorageGridPurchaserNews sgpn = sgpnList.get(0);
		
		StorageChargeInfo storageChargeInfo = storageChargeInfoList.get(0);
		
		orderInformation.setTransactions(OrderConstant.DONE_TAKE_OUT);
		
		entityManager.merge(orderInformation);
		
		sgpn.setPick(1);
		sgpn.setClosing(1);
		sgpn.setTakeawayTime(takeoutTime);
		
		entityManager.merge(sgpn);
		
		storageServiceInfo.setTakeoutTime(takeoutTime);
		storageServiceInfo.setStorageChargeInfo(storageChargeInfo);
		
		float actualTimeLong = Float.parseFloat(new DecimalFormat("0.00").format((takeoutTime.getTime() - storageServiceInfo.getDeliveryTime().getTime()) / 1000F / 60F / 60F));
		
		logger.info("Actual time long -> " + actualTimeLong);
		
		if (storageChargeInfo.getFreePeriod() > actualTimeLong){
			storageServiceInfo.setChargeAmount(0.0D);
			storageServiceInfo.setChargeTime(0.0F);
		} else {
			if (storageChargeInfo.getChargeInterval() > 0) {
				float chargeTimeLong = actualTimeLong - storageChargeInfo.getFreePeriod();
				logger.info("Actual charge time long -> " + chargeTimeLong);
				storageServiceInfo.setChargeTime(chargeTimeLong);
				storageServiceInfo.setChargeAmount(Math.ceil(chargeTimeLong / storageChargeInfo.getChargeInterval()) * storageChargeInfo.getChargeStandard());
			} else {
				storageServiceInfo.setChargeAmount(0.0D);
				storageServiceInfo.setChargeTime(0.0F);
			}
		}
		
		entityManager.merge(storageServiceInfo);

		Map<String, Object> informMap = informMessage.queryInformMessage(storageServiceInfo.getPurchaser().getLanguage(), 7, 4);
		
		String phone = storageServiceInfo.getPurchaser().getPhone();
		String email = storageServiceInfo.getPurchaser().getEmail();
		
		Object[] objs = {orderInformation.getLockers().getLocation().getDescription() + orderInformation.getLockers().getLockersName(), orderInformation.getGroup().getHotline()};
		
		if (null != phone && !"".equals(phone) && informMap.containsKey(InformMessageLocal.SMS_INFORM)){
			String message = ((SmsInfo)informMap.get(InformMessageLocal.SMS_INFORM)).getSmsContent();
			
			message = MessageFormat.format(message, objs);
			
			logger.info("SMS message -> " + message);
			
			new SMSScheduler(phone, message, SMSScheduler.MMS_CAT_CHANNEL, orderInformation.getGroup().getName(), false).start();
			
		} else if (null != email && !"".equals(email) && informMap.containsKey(InformMessageLocal.EMAIL_INFORM)){
			EmailInfo emailInfo = (EmailInfo) informMap.get(InformMessageLocal.EMAIL_INFORM);
			
			String message = emailInfo.getContent();
			
			message = MessageFormat.format(message, objs);
			
			logger.info("E-MAIL message -> " + message);
			
			new EMAILScheduler(email, emailInfo.getTitle(), message).start();	
		}
		
		entityManager.flush();
		
		JSONObject param = new JSONObject();
		param.accumulate("lockers_id", sgpn.getLockersId());
		param.accumulate("store_code", storageRfid);
		param.accumulate("service_type", 1);
		param.accumulate("takeout_time", takeoutTime.getTime());
		
		logger.info(RESTUtil.getRESTInvoke(RESTUtil.TAKEOUT_INFO_CALLBACK_METHOD, param.toString()));
		
		return 0;
	}*/
	
	@SuppressWarnings("unchecked")
	public int safeStorageTakeout(String deviceSn, int gridNo, String storageRfid, String timestamp) {
		logger.info("deviceSn -> " + deviceSn + " gridNo -> " + gridNo + " storageRfid -> " + storageRfid + " timestamp -> " + timestamp);
		
		Date takeoutTime = DateTimeHelper.strToDateTime(timestamp, DateTimeHelper.DEFAULT_DATE_TIME_NOT_SPACE_FORMAT);
		
		Query query  = entityManager.createQuery("select sgpn from StorageGridPurchaserNews sgpn where sgpn.closing = 0 and sgpn.pick = 0 and sgpn.refund = 0 and sgpn.storageGrid.gridNum = :gridNum and sgpn.deviceSn = :deviceSn and sgpn.rfidSn = :rfidSn");
		List<StorageGridPurchaserNews> sgpns = query.setParameter("gridNum", gridNo).setParameter("deviceSn", deviceSn).setParameter("rfidSn", storageRfid).getResultList();
		
		if (sgpns.size() > 0){
			StorageGridPurchaserNews sgpn = (StorageGridPurchaserNews) sgpns.get(0);
			sgpn.setClosing(1);
			sgpn.setPick(1);
			sgpn.setTakeawayTime(takeoutTime);
			entityManager.merge(sgpn);
			
			PickRecords pickRecords = new PickRecords();		
			pickRecords.setCardNumber(sgpn.getCardNumber());
			pickRecords.setGridNum(gridNo);
			pickRecords.setFlag(false);
			pickRecords.setOrderInformationNumber(sgpn.getOrderInformationNumber());
			pickRecords.setRfidSn(storageRfid);
			pickRecords.setInsertTime(DateTimeHelper.dateTimeToStr(takeoutTime, DateTimeHelper.DEFAULT_DATE_TIME_FORMAT));
			entityManager.persist(pickRecords);
			
			List<OrderInformation> list = entityManager.createQuery("select oi from OrderInformation oi where oi.number = '" + sgpn.getOrderInformationNumber() + "'").getResultList();
			
			if (list.size() > 0){
				OrderInformation orderInfo = list.get(0);
				orderInfo.setTransactions(7);
				
				entityManager.merge(orderInfo);
				
				workflowMessageLocal.createWorkflowInfo(sgpn.getOrderInformationNumber(), 1, "会员完成取货...", DateTimeHelper.strToDateTime(DateTimeHelper.dateTimeToStr(new Date(), DateTimeHelper.DEFAULT_YEAR_FORMAT) + CommEntryUtil.getFormatStr(timestamp, 10), DateTimeHelper.DEFAULT_DATE_TIME_NOT_SPACE_FORMAT), "系统", 4);
				
				Map<String, Object> informMap = informMessage.queryInformMessage(orderInfo.getPurchaser().getLanguage(), 7, 4);
				
				String phone = orderInfo.getPurchaser().getPhone();
				String email = orderInfo.getPurchaser().getEmail();
				
				//Object[] objs = {orderInfo.getLockers().getLocation().getDescription() + orderInfo.getLockers().getLockersName(), orderInfo.getGroup().getHotline()};
				Object[] objs = {orderInfo.getLockers().getLocation().getDescription() + orderInfo.getLockers().getLockersName()};
				
				if (null != phone && !"".equals(phone) && informMap.containsKey(InformMessageLocal.SMS_INFORM)){
					String message = ((SmsInfo)informMap.get(InformMessageLocal.SMS_INFORM)).getSmsContent();
					
					message = MessageFormat.format(message, objs);
					
					logger.info("SMS message -> " + message);
					
					//new SMSScheduler(phone, message, objs, "174", orderInfo.getGroup().getSmsChannel(), orderInfo.getGroup().getName(), false).start();
					
					String params="{\"address\":\""+objs[0]+"\"}";
					new AlidayuSMS(phone,"SMS_5420176","收货确认",params,message,new SaveSmsInfo()).start();
					
					workflowMessageLocal.createWorkflowInfo(sgpn.getOrderInformationNumber(), 1, "发送取货信息...", DateTimeHelper.strToDateTime(DateTimeHelper.dateTimeToStr(new Date(), DateTimeHelper.DEFAULT_YEAR_FORMAT) + CommEntryUtil.getFormatStr(timestamp, 10), DateTimeHelper.DEFAULT_DATE_TIME_NOT_SPACE_FORMAT), "系统", 4);
					
				} else if (null != email && !"".equals(email) && informMap.containsKey(InformMessageLocal.EMAIL_INFORM)){
					EmailInfo emailInfo = (EmailInfo) informMap.get(InformMessageLocal.EMAIL_INFORM);
					
					String message = emailInfo.getContent();
					
					message = MessageFormat.format(message, objs);
					
					logger.info("E-MAIL message -> " + message);
					
					new EMAILScheduler(email, emailInfo.getTitle(), message).start();	
					
					workflowMessageLocal.createWorkflowInfo(sgpn.getOrderInformationNumber(), 1, "发送取货信息...", DateTimeHelper.strToDateTime(DateTimeHelper.dateTimeToStr(new Date(), DateTimeHelper.DEFAULT_YEAR_FORMAT) + CommEntryUtil.getFormatStr(timestamp, 10), DateTimeHelper.DEFAULT_DATE_TIME_NOT_SPACE_FORMAT), "系统", 4);
					
				}
				
				entityManager.flush();
				
				JSONObject param = new JSONObject();
				param.accumulate("lockers_id", sgpn.getLockersId());
				param.accumulate("store_code", storageRfid);
				param.accumulate("service_type", 1);
				param.accumulate("takeout_time", takeoutTime.getTime());
				
				logger.info(RESTUtil.getRESTInvoke(RESTUtil.TAKEOUT_INFO_CALLBACK_METHOD, param.toString()));
				
				return 0;
			} else {
				return 6;
			}
		} else {
			return 6;
		}
	}

	@SuppressWarnings("unchecked")
	public int easyStorageTakeout(String deviceSn, int gridNo, String storageRfid, String timestamp) {
		logger.info("deviceSn -> " + deviceSn + " gridNo -> " + gridNo + " storageRfid -> " + storageRfid + " timestamp -> " + timestamp);
		
		Date deliveryTime = DateTimeHelper.strToDateTime(timestamp, DateTimeHelper.DEFAULT_DATE_TIME_NOT_SPACE_FORMAT);
		
		List<ProductBatch> productBatchList  = entityManager.createQuery("select bp from ProductBatch bp where bp.rfidSn = '" + storageRfid + "'").getResultList();
		
		if (null == productBatchList || productBatchList.size() == 0)
			return 6;
		
		OrderInformation orderInformation = productBatchList.get(0).getOrderInformation();
		
		if (null == orderInformation)
			return 6;
		
		List<StorageGridPurchaserNews> sgpnList = entityManager.createQuery("select sgpn from StorageGridPurchaserNews sgpn where closing = 0 and sgpn.refund = 0 and sgpn.delivery = 1 and sgpn.orderInformationNumber = '" + orderInformation.getNumber() + "'").getResultList();
		if (null == sgpnList || sgpnList.size() == 0)
			return 6;
		
		StorageGridPurchaserNews sgpn = sgpnList.get(0);
		
		orderInformation.setTransactions(OrderConstant.DONE_TAKE_OUT);
		
		entityManager.merge(orderInformation);
		
		sgpn.setPick(1);
		sgpn.setClosing(1);
		sgpn.setTakeawayTime(deliveryTime);
		
		entityManager.merge(sgpn);
		
		Map<String, Object> informMap = informMessage.queryInformMessage(orderInformation.getPurchaser().getLanguage(), 7, 4);
		
		String phone = orderInformation.getPurchaser().getPhone();
		String email = orderInformation.getPurchaser().getEmail();
		
		//Object[] objs = {orderInformation.getLockers().getLocation().getDescription() + orderInformation.getLockers().getLockersName(), orderInformation.getGroup().getHotline()};
		Object[] objs = {orderInformation.getLockers().getLocation().getDescription() + orderInformation.getLockers().getLockersName()};
		
		if (null != phone && !"".equals(phone) && informMap.containsKey(InformMessageLocal.SMS_INFORM)){
			String message = ((SmsInfo)informMap.get(InformMessageLocal.SMS_INFORM)).getSmsContent();
			
			message = MessageFormat.format(message, objs);
			
			logger.info("SMS message -> " + message);
			
			//new SMSScheduler(phone, message, objs, "174", orderInformation.getGroup().getSmsChannel(), orderInformation.getGroup().getName(), false).start();
			
			String papams="{\"address\":\""+objs[0]+"\"}";
			new AlidayuSMS(phone,"SMS_5420176","收货确认",papams,message,new SaveSmsInfo()).start();
			
		} else if (null != email && !"".equals(email) && informMap.containsKey(InformMessageLocal.EMAIL_INFORM)){
			EmailInfo emailInfo = (EmailInfo) informMap.get(InformMessageLocal.EMAIL_INFORM);
			
			String message = emailInfo.getContent();
			
			message = MessageFormat.format(message, objs);
			
			logger.info("E-MAIL message -> " + message);
			
			new EMAILScheduler(email, emailInfo.getTitle(), message).start();	
		}
		
		entityManager.flush();
		
		JSONObject param = new JSONObject();
		param.accumulate("lockers_id", sgpn.getLockersId());
		param.accumulate("store_code", storageRfid);
		param.accumulate("service_type", 2);
		param.accumulate("takeout_time", timestamp);
		
		logger.info(RESTUtil.getRESTInvoke(RESTUtil.TAKEOUT_INFO_CALLBACK_METHOD, param.toString()));
		
		return 0;
	}

	@SuppressWarnings("unchecked")
	public int expressTakeout(String deviceSn, int gridNo, String storageRfid, String timestamp) {
		logger.info("deviceSn -> " + deviceSn + " gridNo -> " + gridNo + " storageRfid -> " + storageRfid + " timestamp -> " + timestamp);
		
		Date deliveryTime = DateTimeHelper.strToDateTime(timestamp, DateTimeHelper.DEFAULT_DATE_TIME_NOT_SPACE_FORMAT);
		
		List<ProductBatch> productBatchList  = entityManager.createQuery("select bp from ProductBatch bp where bp.rfidSn = '" + storageRfid + "'").getResultList();
		
		if (null == productBatchList || productBatchList.size() == 0)
			return 6;
		
		OrderInformation orderInformation = productBatchList.get(0).getOrderInformation();
		
		if (null == orderInformation)
			return 6;
		
		List<StorageGridPurchaserNews> sgpnList = entityManager.createQuery("select sgpn from StorageGridPurchaserNews sgpn where closing = 0 and sgpn.refund = 0 and sgpn.delivery = 1 and sgpn.orderInformationNumber = '" + orderInformation.getNumber() + "'").getResultList();
		if (null == sgpnList || sgpnList.size() == 0)
			return 6;
		
		StorageGridPurchaserNews sgpn = sgpnList.get(0);
		
		orderInformation.setTransactions(OrderConstant.DONE_TAKE_OUT);
		
		entityManager.merge(orderInformation);
		
		sgpn.setPick(1);
		sgpn.setClosing(1);
		sgpn.setTakeawayTime(deliveryTime);
		
		entityManager.merge(sgpn);
		
		Map<String, Object> informMap = informMessage.queryInformMessage(orderInformation.getPurchaser().getLanguage(), 7, 4);
		
		String phone = orderInformation.getPurchaser().getPhone();
		String email = orderInformation.getPurchaser().getEmail();
		
		//Object[] objs = {orderInformation.getLockers().getLocation().getDescription() + orderInformation.getLockers().getLockersName(), orderInformation.getGroup().getHotline()};
		Object[] objs = {orderInformation.getLockers().getLocation().getDescription() + orderInformation.getLockers().getLockersName()};
		
		
		if (null != phone && !"".equals(phone) && informMap.containsKey(InformMessageLocal.SMS_INFORM)){
			String message = ((SmsInfo)informMap.get(InformMessageLocal.SMS_INFORM)).getSmsContent();
			
			message = MessageFormat.format(message, objs);
			
			logger.info("SMS message -> " + message);
			
			//new SMSScheduler(phone, message, objs, "174", orderInformation.getGroup().getSmsChannel(), orderInformation.getGroup().getName(), false).start();
			
			String params="{\"address\":\""+objs[0]+"\"}";
			new AlidayuSMS(phone,"SMS_5420176","收货确认",params,message,new SaveSmsInfo()).start();
			
		} else if (null != email && !"".equals(email) && informMap.containsKey(InformMessageLocal.EMAIL_INFORM)){
			EmailInfo emailInfo = (EmailInfo) informMap.get(InformMessageLocal.EMAIL_INFORM);
			
			String message = emailInfo.getContent();
			
			message = MessageFormat.format(message, objs);
			
			logger.info("E-MAIL message -> " + message);
			
			new EMAILScheduler(email, emailInfo.getTitle(), message).start();	
		}
		
		entityManager.flush();

		return 0;
	}
	
	@SuppressWarnings("unchecked")
	public int recycleTakeout(String deviceSn, int gridNo, String storageRfid, String timestamp) {
		logger.info("deviceSn -> " + deviceSn + " gridNo -> " + gridNo + " storageRfid -> " + storageRfid + " timestamp -> " + timestamp);
		
		Date deliveryTime = DateTimeHelper.strToDateTime(timestamp, DateTimeHelper.DEFAULT_DATE_TIME_NOT_SPACE_FORMAT);
		
		List<ProductBatch> productBatchList  = entityManager.createQuery("select bp from ProductBatch bp where bp.rfidSn = '" + storageRfid + "'").getResultList();
		
		if (null == productBatchList || productBatchList.size() == 0)
			return 6;
		
		OrderInformation orderInformation = productBatchList.get(0).getOrderInformation();
		
		if (null == orderInformation)
			return 6;
		
		List<StorageGridPurchaserNews> sgpnList = entityManager.createQuery("select sgpn from StorageGridPurchaserNews sgpn where closing = 0 and sgpn.refund = 0 and sgpn.delivery = 1 and sgpn.orderInformationNumber = '" + orderInformation.getNumber() + "'").getResultList();
		if (null == sgpnList || sgpnList.size() == 0)
			return 6;
		
		StorageGridPurchaserNews sgpn = sgpnList.get(0);
		
		orderInformation.setTransactions(OrderConstant.DONE_TAKE_OUT);
		
		entityManager.merge(orderInformation);
		
		sgpn.setPick(1);
		sgpn.setClosing(1);
		sgpn.setTakeawayTime(deliveryTime);
		
		entityManager.merge(sgpn);
		
		entityManager.flush();

		return 0;
	}

}
